perf: optimize hex decoding in json (1.8x faster in binary-heavy)#9091
perf: optimize hex decoding in json (1.8x faster in binary-heavy)#9091alamb merged 7 commits intoapache:mainfrom
Conversation
30f160e to
4a6b5d4
Compare
| impl ArrayDecoder for FixedSizeBinaryArrayDecoder { | ||
| fn decode(&mut self, tape: &Tape<'_>, pos: &[u32]) -> Result<ArrayData, ArrowError> { | ||
| let mut builder = FixedSizeBinaryBuilder::with_capacity(pos.len(), self.len); | ||
| let mut scratch = Vec::with_capacity(self.len as usize); |
There was a problem hiding this comment.
why self.len? Isn't that the length of the input? Also the scratch used below is different (no initial capacity)
There was a problem hiding this comment.
Good catch. Here self.len comes from FixedSizeBinary and represents the decoded byte width, not the input hex string length. The input string length is expected to be 2 * len. For variable-width types we use Vec::new() and reserve per value instead.
|
run benchmark json-reader |
|
(I fixed a bug in my benchmark runner that didn't allow |
c8ed14d to
2571386
Compare
|
🤖 |
|
🤖: Benchmark completed Details
|
|
Our benchmarks show 4x faster -- nice work @Weijun-H |
|
Thanks for the reviews @Jefffrey |
…ache#9091) # Which issue does this PR close? <!-- We generally require a GitHub issue to be filed for all bug fixes and enhancements and this helps us generate change logs for our releases. You can link an issue to this PR using the GitHub syntax. --> - Closes #NNN. # Rationale for this change Improve JSON binary decoding performance by avoiding per-value allocations and enabling direct hex decoding into builders. <!-- Why are you proposing this change? If this is already explained clearly in the issue then this section is not needed. Explaining clearly why changes are proposed helps reviewers understand your changes and offer better suggestions for fixes. --> # What changes are included in this PR? Optimized binary hex decoding paths to reduce allocations and improve throughput. ``` decode_binary_hex_json time: [3.6780 ms 3.6953 ms 3.7150 ms] change: [−61.051% −60.818% −60.565%] (p = 0.00 < 0.05) Performance has improved. Found 8 outliers among 100 measurements (8.00%) 5 (5.00%) high mild 3 (3.00%) high severe decode_fixed_binary_hex_json time: [4.0404 ms 4.1400 ms 4.2901 ms] change: [−56.149% −55.040% −53.330%] (p = 0.00 < 0.05) Performance has improved. Found 19 outliers among 100 measurements (19.00%) 7 (7.00%) high mild 12 (12.00%) high severe decode_binary_view_hex_json time: [4.3731 ms 4.4242 ms 4.4767 ms] change: [−53.305% −52.771% −52.239%] (p = 0.00 < 0.05) Performance has improved. Found 1 outliers among 100 measurements (1.00%) 1 (1.00%) high mild ``` <!-- There is no need to duplicate the description in the issue here but it is sometimes worth providing a summary of the individual changes in this PR. --> # Are these changes tested? Yes <!-- We typically require tests for all PRs in order to: 1. Prevent the code from being accidentally broken by subsequent changes 2. Serve as another way to document the expected behavior of the code If tests are not included in your PR, please explain why (for example, are they covered by existing tests)? --> # Are there any user-facing changes? No <!-- If there are user-facing changes then we may require documentation to be updated before approving the PR. If there are any breaking changes to public APIs, please call them out. -->
Which issue does this PR close?
Rationale for this change
Improve JSON binary decoding performance by avoiding per-value allocations and enabling direct hex decoding into builders.
What changes are included in this PR?
Optimized binary hex decoding paths to reduce allocations and improve throughput.
Are these changes tested?
Yes
Are there any user-facing changes?
No